import json

from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.views import View
from fdfs_client.client import Fdfs_client

from utils.response_code import RET, error_map
from .models import Area, House, Facility, HouseImage


class AreaView(View):
    def get(self, request):
        """获取城区列表"""

        areas = Area.objects.all()
        areas_list = []
        for area in areas:
            areas_list.append({
                'aid': area.id,
                'aname': area.name
            })

        return JsonResponse({
            'errno': '0',
            'errmsg': '获取成功',
            'data': areas_list
        })


class HouseView(LoginRequiredMixin, View):
    def post(self, request):
        """发布房源"""

        recv_data = json.loads(request.body)
        facilities = recv_data.pop('facility')

        house = House.objects.create(user=request.user, **recv_data)

        for facility in facilities:
            house.facility.add(Facility.objects.get(id=facility))

        house.save()

        return JsonResponse({
            'errno': 0,
            'errmsg': '发布成功',
            'data': {
                'house_id': house.id
            }
        })

    def get(self, request):
        """搜索"""

        # 获取数据
        area_id = request.GET.get('aid')
        start_date = request.GET.get('sd')
        end_date = request.GET.get('ed')
        sort_key = request.GET.get('sk')
        page = request.GET.get('p')

        # 数据过滤
        houses = House.objects.all()

        if area_id:
            houses = houses.filter(area_id=area_id)

        if sort_key == 'booking':
            houses = houses.order_by('-order_count')
        elif sort_key == 'price-inc':
            houses = houses.order_by('price')
        elif sort_key == 'price-des':
            houses = houses.order_by('-price')
        else:
            houses = houses.order_by('-create_time')

        from datetime import datetime
        if start_date:
            start_date = datetime.strptime(start_date, '%Y-%m-%d').date()

            house_list = []
            if not end_date:
                for house in houses:
                    orders = house.order_set.all()
                    for order in orders:
                        if start_date < order.begin_date or start_date >= order.end_date:
                            pass
                        else:
                            break
                    else:
                        house_list.append(house)

            else:
                end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
                days = (end_date - start_date).days

                from django.db.models import Q
                houses = houses.filter(Q(min_days__lte=days) & (Q(max_days=0) | Q(max_days__gte=days)))

                for house in houses:
                    orders = house.order_set.all()
                    for order in orders:
                        if start_date >= order.end_date or end_date <= order.begin_date:
                            pass
                        else:
                            break
                    else:
                        house_list.append(house)

            # 分页
            count = len(house_list)
            if page:
                page = int(page)
            else:
                page = 1
            from math import ceil
            total_page = ceil(count / 2)

            if page < total_page:
                res_houses = house_list[(page - 1) * 2: page * 2]
            else:
                res_houses = house_list[(page - 1) * 2:]

            house_data = []
            for house in res_houses:
                try:
                    user_avatar = house.user.avatar.url
                except:
                    user_avatar = ''
                house_data.append({
                    "address": house.address,
                    "area_name": house.area.name,
                    "ctime": house.create_time.date(),
                    "house_id": house.id,
                    "img_url": settings.BASE_URL + house.index_image_url,
                    "order_count": house.order_count,
                    "price": house.price,
                    "room_count": house.room_count,
                    "title": house.title,
                    "user_avatar": user_avatar
                })

            return JsonResponse({
                'errno': 0,
                'errmsg': '请求成功',
                'data': {
                    'houses': house_data,
                    'total_page': total_page
                }
            })


class HouseImageView(LoginRequiredMixin, View):
    def post(self, request, house_id):
        """上传房源图片"""

        # 获取房源对象
        try:
            house = House.objects.get(id=house_id)
        except:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        # 使用fdfs上传图片
        image = request.FILES.get('house_image')
        image_buffer = image.read()
        fdfs_client = Fdfs_client(settings.BASE_DIR + '/utils/fdfs/client.conf')
        result = fdfs_client.upload_by_buffer(image_buffer)

        # 判断上传状态
        if result['Status'] != 'Upload successed.':
            return JsonResponse({
                'errno': RET.THIRDERR,
                'errmsg': error_map[RET.THIRDERR]
            })

        # 获取图片远程地址
        image_url = result['Remote file_id']
        house.index_image_url = image_url
        house.save()
        HouseImage.objects.create(house=house, url=image_url)

        # 返回响应
        return JsonResponse({
            'data': {
                'url': settings.BASE_URL + image_url
            },
            'errno': 0,
            'errmsg': '图片上传成功'
        })


class MyHouseView(LoginRequiredMixin, View):
    def get(self, request):
        """获取我发布的房源信息"""

        user = request.user
        houses = user.houses.all()

        houses_list = []
        for house in houses:
            try:
                user_avatar = house.user.avatar.url
            except:
                user_avatar = ''

            houses_list.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time.date(),
                "house_id": house.id,
                "img_url": settings.BASE_URL + house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": user_avatar
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': 'ok',
            'data': {
                'houses': houses_list
            }
        })


class HomeRecommendView(View):
    def get(self, request):
        """获取首页推荐"""

        houses = House.objects.order_by('-create_time')[0: 5]
        houses_list = []
        for house in houses:
            houses_list.append({
                'house_id': house.id,
                'img_url': settings.BASE_URL + house.index_image_url,
                'title': house.title
            })

        return JsonResponse({
            'errno': '0',
            'errmsg': 'OK',
            'data': houses_list
        })


class HouseDetailView(View):
    def get(self, request, house_id):
        """房屋详情页"""

        try:
            house = House.objects.get(id=house_id)
        except:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        orders = house.order_set.all()
        comments = []
        for order in orders:
            comments.append({
                'comment': order.comment,
                'ctime': order.create_time,
                'user_name': order.user.username
            })

        house_data = {
            "acreage": house.acreage,
            "address": house.address,
            "beds": house.beds,
            "capacity": house.capacity,
            "comments": comments,
            "deposit": house.deposit,
            "facilities": [facility.id for facility in house.facility],
            "hid": house.id,
            "img_urls": [settings.BASE_URL + image.url for image in HouseImage.objects.filter(house=house)],
            "max_days": house.max_days,
            "min_days": house.min_days,
            "price": house.price,
            "room_count": house.room_count,
            "title": house.title,
            "unit": house.unit,
            "user_avatar": house.user.avatar.url,
            "user_id": house.user.id,
            "user_name": house.user.username
        }

        if request.user.is_authenticated:
            user_id = request.user.id
        else:
            user_id = -1

        return JsonResponse({
            'errno': 0,
            'errmsg': 'OK',
            'data': {
                'house': house_data,
                'user_id': user_id
            }
        })